home *** CD-ROM | disk | FTP | other *** search
/ Clickx 47 / Clickx 47.iso / assets / software / Miro_Installer.exe / xulrunner / chrome / toolkit.jar / content / mozapps / extensions / update.js < prev    next >
Encoding:
Text File  |  2005-11-03  |  17.4 KB  |  511 lines

  1. //@line 37 "/c/mozilla/toolkit/mozapps/extensions/content/update.js"
  2.  
  3. //
  4. // This UI can be opened from the following places, and in the following modes:
  5. //
  6. // - from the Version Compatibility Checker at startup
  7. //    as the application starts a check is done to see if the application being
  8. //    started is the same version that was started last time. If it isn't, a
  9. //    list of UpdateItems that are incompatible with the verison being 
  10. //    started is generated and this UI opened with that list. This UI then
  11. //    offers to check for updates to those UpdateItems that are compatible
  12. //    with the version of the application being started. 
  13. //    
  14. //    In this mode, the wizard is opened to panel 'mismatch'. 
  15.  
  16. const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
  17. const nsIAUCL = Components.interfaces.nsIAddonUpdateCheckListener;
  18.  
  19. const PREF_UPDATE_EXTENSIONS_ENABLED            = "extensions.update.enabled";
  20. const PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED  = "extensions.update.autoUpdateEnabled";
  21.  
  22. var gShowMismatch = null;
  23. var gUpdateTypes  = null;
  24.  
  25. var gUpdateWizard = {
  26.   // The items to check for updates for (e.g. an extension, some subset of extensions, 
  27.   // all extensions, a list of compatible extensions, etc...)
  28.   items: [],
  29.   // The items that we found updates available for
  30.   itemsToUpdate: [],
  31.   // The items that we successfully installed updates for
  32.   updatedCount: 0,
  33.   shouldSuggestAutoChecking: false,
  34.   shouldAutoCheck: false,
  35.   
  36.   remainingExtensionUpdateCount: 0,
  37.   
  38.   succeeded: true,
  39.   
  40.   init: function ()
  41.   {
  42.     var em = Components.classes["@mozilla.org/extensions/manager;1"]
  43.                         .getService(Components.interfaces.nsIExtensionManager);
  44.     // Retrieve all items in order to sync their app compatibility information
  45.     this.items = em.getItemList(nsIUpdateItem.TYPE_ADDON, { });
  46.     var pref = 
  47.         Components.classes["@mozilla.org/preferences-service;1"].
  48.         getService(Components.interfaces.nsIPrefBranch);
  49.     this.shouldSuggestAutoChecking = 
  50.       gShowMismatch && 
  51.       !pref.getBoolPref(PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED);
  52.  
  53.     document.documentElement.currentPage = 
  54.       document.getElementById("versioninfo");
  55.   },
  56.   
  57.   onWizardFinish: function ()
  58.   {
  59.     var pref = Components.classes["@mozilla.org/preferences-service;1"]
  60.                          .getService(Components.interfaces.nsIPrefBranch);
  61.     if (this.shouldSuggestAutoChecking)
  62.       pref.setBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED, this.shouldAutoCheck); 
  63.   },
  64.   
  65.   _setUpButton: function (aButtonID, aButtonKey, aDisabled)
  66.   {
  67.     var strings = document.getElementById("updateStrings");
  68.     var button = document.documentElement.getButton(aButtonID);
  69.     if (aButtonKey) {
  70.       button.label = strings.getString(aButtonKey);
  71.       try {
  72.         button.accesskey = strings.getString(aButtonKey + "Accesskey");
  73.       }
  74.       catch (e) {
  75.       }
  76.     }
  77.     button.disabled = aDisabled;
  78.   },
  79.   
  80.   setButtonLabels: function (aBackButton, aBackButtonIsDisabled, 
  81.                              aNextButton, aNextButtonIsDisabled,
  82.                              aCancelButton, aCancelButtonIsDisabled)
  83.   {
  84.     this._setUpButton("back", aBackButton, aBackButtonIsDisabled);
  85.     this._setUpButton("next", aNextButton, aNextButtonIsDisabled);
  86.     this._setUpButton("cancel", aCancelButton, aCancelButtonIsDisabled);
  87.   },
  88.   
  89.   /////////////////////////////////////////////////////////////////////////////
  90.   // Update Errors
  91.   errorItems: [],
  92.   showErrors: function (aState, aErrors)
  93.   {
  94.     openDialog("chrome://mozapps/content/update/errors.xul", "", 
  95.                "modal", { state: aState, errors: aErrors });
  96.   },
  97.   
  98.   showUpdateCheckErrors: function ()
  99.   {
  100.     var errors = [];
  101.     for (var i = 0; i < this.errorItems.length; ++i)
  102.       errors.push({ name: this.errorItems[i].name, error: true, 
  103.                     item: this.errorItems[i] });
  104.     this.showErrors("checking", errors);
  105.   },
  106.  
  107.   checkForErrors: function (aElementIDToShow)
  108.   {
  109.     if (this.errorOnGeneric || this.errorItems.length > 0)
  110.       document.getElementById(aElementIDToShow).hidden = false;
  111.   },
  112.   
  113.   onWizardClose: function (aEvent)
  114.   {
  115.     if (gInstallingPage._installing) {
  116.       var os = Components.classes["@mozilla.org/observer-service;1"]
  117.                          .getService(Components.interfaces.nsIObserverService);
  118.       os.notifyObservers(null, "xpinstall-progress", "cancel");
  119.       return false;
  120.     }    
  121.     return true;
  122.   }
  123. };
  124.  
  125. var gVersionInfoPage = {
  126.   _completeCount: 0,
  127.   _totalCount: 0,
  128.   onPageShow: function ()
  129.   {
  130.     gUpdateWizard.setButtonLabels(null, true, 
  131.                                   "nextButtonText", true, 
  132.                                   "cancelButtonText", false);
  133.     var em = Components.classes["@mozilla.org/extensions/manager;1"]
  134.                        .getService(Components.interfaces.nsIExtensionManager);
  135.     // Synchronize the app compatibility info for all items by specifying 2 for
  136.     // the versionUpdateOnly parameter.
  137.     em.update([], 0, 2, this);
  138.   },
  139.  
  140.   /////////////////////////////////////////////////////////////////////////////
  141.   // nsIAddonUpdateCheckListener
  142.   onUpdateStarted: function() {
  143.     this._totalCount = gUpdateWizard.items.length;
  144.   },
  145.   
  146.   onUpdateEnded: function() {
  147.     var em = Components.classes["@mozilla.org/extensions/manager;1"]
  148.                        .getService(Components.interfaces.nsIExtensionManager);
  149.     // Retrieve the remaining incompatible items.
  150.     gUpdateWizard.items = em.getIncompatibleItemList(null, null,
  151.                                                      nsIUpdateItem.TYPE_ADDON,
  152.                                                      true, { });
  153.     if (gUpdateWizard.items.length > 0) {
  154.       // There are still incompatible addons, inform the user.
  155.       document.documentElement.currentPage = 
  156.         document.getElementById("mismatch");
  157.     }
  158.     else {
  159.       // VersionInfo compatibility updates resolved all compatibility problems,
  160.       // close this window and continue starting the application...
  161.       //XXX Bug 314754 - We need to use setTimeout to close the window due to
  162.       // the EM using xmlHttpRequest when checking for updates.
  163.       setTimeout(close, 0);
  164.     }
  165.   },
  166.   
  167.   onAddonUpdateStarted: function(addon) {
  168.   },
  169.   
  170.   onAddonUpdateEnded: function(addon, status) {
  171.     if (status == nsIAUCL.STATUS_VERSIONINFO) {
  172.       for (var i = 0; i < gUpdateWizard.items.length; ++i) {
  173.         var item = gUpdateWizard.items[i].QueryInterface(nsIUpdateItem);
  174.         if (addon.id == item.id) {
  175.           gUpdateWizard.items.splice(i, 1);
  176.           break;
  177.         }
  178.       }
  179.     }
  180.     ++this._completeCount;
  181.  
  182.     // Update the status text and progress bar
  183.     var progress = document.getElementById("versioninfo.progress");
  184.     progress.mode = "normal";
  185.     progress.value = Math.ceil((this._completeCount / this._totalCount) * 100);
  186.   },
  187.   
  188.   /////////////////////////////////////////////////////////////////////////////
  189.   // nsISupports
  190.   QueryInterface: function(iid) {
  191.     if (!iid.equals(Components.interfaces.nsIAddonUpdateCheckListener) && 
  192.         !iid.equals(Components.interfaces.nsISupports))
  193.       throw Components.results.NS_ERROR_NO_INTERFACE;
  194.     return this;
  195.   }
  196. };
  197.  
  198. var gMismatchPage = {
  199.   onPageShow: function ()
  200.   {
  201.     gUpdateWizard.setButtonLabels(null, true, 
  202.                                   "mismatchCheckNow", false, 
  203.                                   "mismatchDontCheck", false);
  204.     document.documentElement.getButton("next").focus();
  205.  
  206.     var incompatible = document.getElementById("mismatch.incompatible");
  207.     for (var i = 0; i < gUpdateWizard.items.length; ++i) {
  208.       var item = gUpdateWizard.items[i].QueryInterface(nsIUpdateItem);
  209.       var listitem = document.createElement("listitem");
  210.       listitem.setAttribute("label", item.name + " " + item.version);
  211.       incompatible.appendChild(listitem);
  212.     }
  213.   }
  214. };
  215.  
  216. var gUpdatePage = {
  217.   _completeCount: 0,
  218.   onPageShow: function ()
  219.   {
  220.     gUpdateWizard.setButtonLabels(null, true, 
  221.                                   "nextButtonText", true, 
  222.                                   "cancelButtonText", false);
  223.     document.documentElement.getButton("next").focus();
  224.  
  225.     gUpdateWizard.errorItems = [];
  226.     
  227.     var em = Components.classes["@mozilla.org/extensions/manager;1"]
  228.                        .getService(Components.interfaces.nsIExtensionManager);
  229.     em.update(gUpdateWizard.items, gUpdateWizard.items.length, false, this);
  230.   },
  231.  
  232.   /////////////////////////////////////////////////////////////////////////////
  233.   // nsIAddonUpdateCheckListener
  234.   onUpdateStarted: function() {
  235.   },
  236.   
  237.   onUpdateEnded: function() {
  238.     var nextPage = document.getElementById("noupdates");
  239.     if (gUpdateWizard.itemsToUpdate.length > 0)
  240.       nextPage = document.getElementById("found");
  241.     document.documentElement.currentPage = nextPage;
  242.   },
  243.   
  244.   onAddonUpdateStarted: function(addon) {
  245.   },
  246.   
  247.   onAddonUpdateEnded: function(addon, status) {
  248.     if (status == nsIAUCL.STATUS_UPDATE)
  249.       gUpdateWizard.itemsToUpdate.push(addon);
  250.     else if (status == nsIAUCL.STATE_ERROR)
  251.       gUpdateWizard.errorItems.push(addon);
  252.       
  253.     ++this._completeCount;
  254.  
  255.     // Update the status text and progress bar
  256.     var updateStrings = document.getElementById("updateStrings");
  257.     var status = document.getElementById("checking.status");
  258.     var statusString = updateStrings.getFormattedString("checkingPrefix", [addon.name]);
  259.     status.setAttribute("value", statusString);
  260.  
  261.     var progress = document.getElementById("checking.progress");
  262.     progress.value = Math.ceil((this._completeCount / gUpdateWizard.items.length) * 100);
  263.   },
  264.   
  265.   /////////////////////////////////////////////////////////////////////////////
  266.   // nsISupports
  267.   QueryInterface: function(iid) {
  268.     if (!iid.equals(Components.interfaces.nsIAddonUpdateCheckListener) && 
  269.         !iid.equals(Components.interfaces.nsISupports))
  270.       throw Components.results.NS_ERROR_NO_INTERFACE;
  271.     return this;
  272.   }
  273. };
  274.  
  275. var gFoundPage = {
  276.   _nonAppItems: [],
  277.   
  278.   _newestInfo: null,
  279.  
  280.   buildAddons: function ()
  281.   {
  282.     var hasExtensions = false;
  283.     var foundAddonsList = document.getElementById("found.addons.list");
  284.     var uri = Components.classes["@mozilla.org/network/standard-url;1"]
  285.                         .createInstance(Components.interfaces.nsIURI);
  286.     var itemCount = gUpdateWizard.itemsToUpdate.length;
  287.     for (var i = 0; i < itemCount; ++i) {
  288.       var item = gUpdateWizard.itemsToUpdate[i];
  289.       var checkbox = document.createElement("checkbox");
  290.       foundAddonsList.appendChild(checkbox);
  291.       checkbox.setAttribute("type", "update");
  292.       checkbox.label        = item.name + " " + item.version;
  293.       checkbox.setAttribute("URL", item.xpiURL);
  294.       checkbox.setAttribute("hash", item.xpiHash);
  295.       checkbox.infoURL      = "";
  296.       checkbox.internalName = "";
  297.       uri.spec              = item.xpiURL;
  298.       checkbox.setAttribute("source", uri.host);
  299.       checkbox.checked      = true;
  300.       hasExtensions         = true;
  301.     }
  302.  
  303.     if (hasExtensions) {
  304.       var addonsHeader = document.getElementById("addons");
  305.       var strings = document.getElementById("updateStrings");
  306.       addonsHeader.label = strings.getFormattedString("updateTypeExtensions", [itemCount]);
  307.       addonsHeader.collapsed = false;
  308.     }
  309.   },
  310.  
  311.   _initialized: false,
  312.   onPageShow: function ()
  313.   {
  314.     gUpdateWizard.setButtonLabels(null, true, 
  315.                                   "installButtonText", false, 
  316.                                   null, false);
  317.     document.documentElement.getButton("next").focus();
  318.     
  319.     var updates = document.getElementById("found.updates");
  320.     if (!this._initialized) {
  321.       this._initialized = true;
  322.       updates.computeSizes();
  323.       this.buildAddons();
  324.     }
  325.         
  326.     var kids = updates._getRadioChildren();
  327.     for (var i = 0; i < kids.length; ++i) {
  328.       if (kids[i].collapsed == false) {
  329.         updates.selectedIndex = i;
  330.         break;
  331.       }
  332.     }
  333.   },
  334.     
  335.   onSelect: function (aEvent)
  336.   {
  337.     var updates = document.getElementById("found.updates");
  338.     var oneChecked = false;
  339.     var items = updates.selectedItem.getElementsByTagName("checkbox");
  340.     for (var i = 0; i < items.length; ++i) {  
  341.       if (items[i].checked) {
  342.         oneChecked = true;
  343.         break;
  344.       }
  345.     }
  346.  
  347.     var strings = document.getElementById("updateStrings");
  348.     gUpdateWizard.setButtonLabels(null, true, 
  349.                                   "installButtonText", true, 
  350.                                   null, false);
  351.     var text = strings.getString("foundInstructions");
  352.     document.getElementById("found").setAttribute("next", "installing"); 
  353.     document.documentElement.getButton("next").disabled = !oneChecked;
  354.  
  355.     var foundInstructions = document.getElementById("foundInstructions");
  356.     while (foundInstructions.hasChildNodes())
  357.       foundInstructions.removeChild(foundInstructions.firstChild);
  358.     foundInstructions.appendChild(document.createTextNode(text));
  359.   }
  360. };
  361.  
  362. var gInstallingPage = {
  363.   _installing       : false,
  364.   _restartRequired  : false,
  365.   _objs             : [],
  366.   
  367.   onPageShow: function ()
  368.   {
  369.     gUpdateWizard.setButtonLabels(null, true, 
  370.                                   "nextButtonText", true, 
  371.                                   null, true);
  372.  
  373.     // Get XPInstallManager and kick off download/install 
  374.     // process, registering us as an observer. 
  375.     var items = [];
  376.     var hashes = [];
  377.     this._objs = [];
  378.     
  379.     this._restartRequired = false;
  380.     
  381.     gUpdateWizard.remainingExtensionUpdateCount = gUpdateWizard.itemsToUpdate.length;
  382.  
  383.     var updates = document.getElementById("found.updates");
  384.     var checkboxes = updates.selectedItem.getElementsByTagName("checkbox");
  385.     for (var i = 0; i < checkboxes.length; ++i) {
  386.       if (checkboxes[i].type == "update" && checkboxes[i].checked) {
  387.         items.push(checkboxes[i].URL);
  388.         hashes.push(checkboxes[i].hash ? checkboxes[i].hash : null);
  389.         this._objs.push({ name: checkboxes[i].label });
  390.       }
  391.     }
  392.     
  393.     var xpimgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
  394.                            .createInstance(Components.interfaces.nsIXPInstallManager);
  395.     xpimgr.initManagerWithHashes(items, hashes, items.length, this);
  396.   },
  397.   
  398.   /////////////////////////////////////////////////////////////////////////////
  399.   // nsIXPIProgressDialog
  400.   onStateChange: function (aIndex, aState, aValue)
  401.   {
  402.     var strings = document.getElementById("updateStrings");
  403.  
  404.     const nsIXPIProgressDialog = Components.interfaces.nsIXPIProgressDialog;
  405.     switch (aState) {
  406.     case nsIXPIProgressDialog.DOWNLOAD_START:
  407.       var label = strings.getFormattedString("downloadingPrefix", [this._objs[aIndex].name]);
  408.       var actionItem = document.getElementById("actionItem");
  409.       actionItem.value = label;
  410.       break;
  411.     case nsIXPIProgressDialog.DOWNLOAD_DONE:
  412.     case nsIXPIProgressDialog.INSTALL_START:
  413.       var label = strings.getFormattedString("installingPrefix", [this._objs[aIndex].name]);
  414.       var actionItem = document.getElementById("actionItem");
  415.       actionItem.value = label;
  416.       this._installing = true;
  417.       break;
  418.     case nsIXPIProgressDialog.INSTALL_DONE:
  419.       switch (aValue) {
  420.       case 999: 
  421.         this._restartRequired = true;
  422.         break;
  423.       case 0: 
  424.         --gUpdateWizard.remainingExtensionUpdateCount;
  425.         break;
  426.       }
  427.       break;
  428.     case nsIXPIProgressDialog.DIALOG_CLOSE:
  429.       this._installing = false;
  430.       var nextPage = this._errors ? "errors" : (this._restartRequired ? "restart" : "finished");
  431.       document.getElementById("installing").setAttribute("next", nextPage);
  432.       document.documentElement.advance();
  433.       break;
  434.     }
  435.   },
  436.   
  437.   _objs: [],
  438.   _errors: false,
  439.   
  440.   onProgress: function (aIndex, aValue, aMaxValue)
  441.   {
  442.     var downloadProgress = document.getElementById("downloadProgress");
  443.     downloadProgress.value = Math.ceil((aValue/aMaxValue) * 100);
  444.   }
  445. };
  446.  
  447. var gErrorsPage = {
  448.   onPageShow: function ()
  449.   {
  450.     document.documentElement.getButton("finish").focus();
  451.     gUpdateWizard.succeeded = false;
  452.   },
  453.   
  454.   onShowErrors: function ()
  455.   {
  456.     gUpdateWizard.showErrors("install", gInstallingPage._objs);
  457.   }  
  458. };
  459.  
  460. var gFinishedPage = {
  461.   onPageShow: function ()
  462.   {
  463.     gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
  464.     document.documentElement.getButton("finish").focus();
  465.     
  466.     var iR = document.getElementById("incompatibleRemaining");
  467.     var iR2 = document.getElementById("incompatibleRemaining2");
  468.     var fEC = document.getElementById("finishedEnableChecking");
  469.  
  470.     if (gUpdateWizard.shouldSuggestAutoChecking) {
  471.       iR.hidden = true;
  472.       iR2.hidden = false;
  473.       fEC.hidden = false;
  474.       fEC.click();
  475.     }
  476.     else {
  477.       iR.hidden = false;
  478.       iR2.hidden = true;
  479.       fEC.hidden = true;
  480.     }
  481.     
  482.     if (gShowMismatch) {
  483.       document.getElementById("finishedMismatch").hidden = false;
  484.       document.getElementById("incompatibleAlert").hidden = false;
  485.     }
  486.   }
  487. };
  488.  
  489. var gNoUpdatesPage = {
  490.   onPageShow: function (aEvent)
  491.   {
  492.     gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
  493.     document.documentElement.getButton("finish").focus();
  494.     if (gShowMismatch) {
  495.       document.getElementById("introUser").hidden = true;
  496.       document.getElementById("introMismatch").hidden = false;
  497.       document.getElementById("mismatchNoUpdates").hidden = false;
  498.         
  499.       if (gUpdateWizard.shouldSuggestAutoChecking) {
  500.         document.getElementById("mismatchIncompatibleRemaining").hidden = true;
  501.         document.getElementById("mismatchIncompatibleRemaining2").hidden = false;
  502.         document.getElementById("mismatchFinishedEnableChecking").hidden = false;
  503.       }
  504.     }
  505.  
  506.     gUpdateWizard.succeeded = false;
  507.     gUpdateWizard.checkForErrors("updateCheckErrorNotFound");
  508.   }
  509. };
  510.  
  511.